package xcmg.device.service;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.warehouse.WarehouseDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.SaleIntentionMapper;
import xcmg.device.dao.mapper.abnormal.AbnormalOutMapper;
import xcmg.device.dao.mapper.warehouse.AbnormalInMapper;
import xcmg.device.dao.mapper.warehouse.BillTypeConfigMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseAreaDOMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDOMapper;
import xcmg.device.service.vo.ExternalParamCheckVO;

import java.util.HashSet;
import java.util.List;

/**
 * 外部接口参数校验
 *
 * @author wangyong1015
 */
@Service
public class ExternalParamCheckService {

    @Autowired
    private WarehouseDOMapper warehouseDOMapper;

    @Autowired
    private WarehouseAreaDOMapper warehouseAreaDOMapper;

    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private BillTypeConfigMapper billTypeConfigMapper;

    @Autowired
    private SaleIntentionMapper saleIntentionMapper;

    @Autowired
    private AbnormalInMapper abnormalInMapper;

    @Autowired
    private AbnormalOutMapper abnormalOutMapper;


    public void checkParam(ExternalParamCheckVO param) throws Exception {
        String orgId = getOrgIdBySapCode(param.getSapCode());
        checkAbnormalOutNo(param.getAbnormalOutNo(), orgId);
        checkDictionaryIntegrity(param);
        checkTypeId(param.getTypeId());
        checkInWarehouse(orgId, param.getInLocation(), param.getInArea());
        checkOutWarehouse(orgId, param.getOutLocation(), param.getOutArea());
        checkMaterialsNos(param.getMaterialsNos(), orgId);
        checkSaleNo(param.getSaleNo(), orgId);
        checkAbnormalInNo(param.getAbnormalInNo(), orgId);
        checkSameWarehouseArea(param.getInLocation(), param.getInArea(), param.getOutLocation(), param.getOutArea());
    }

    /**
     * 根据sapCode获取orgId
     *
     * @param sapCode
     * @return
     * @throws Exception
     */
    public String getOrgIdBySapCode(String sapCode) throws Exception {
        CompanyInfoDO companyInfoDO = companyInfoMapper.itemBySap(sapCode);
        if (null == companyInfoDO) {
            throw new Exception("sapCode错误");
        }
        return companyInfoDO.getOrgId();
    }

    /**
     * 根据零件编码获取零件信息*/
    public PriMaterialsDO getMaterialsInfo(String materialsNo){
        if(StringUtils.isEmpty(materialsNo)){
            return null;
        }
        PriMaterialsDO priMaterialsDO = priMaterialsMapper.itemByNoOnly(materialsNo);
        return priMaterialsDO;
    }

    /**
     * 校验调入仓库、库区是否存在
     *
     * @param orgId
     * @param inLocation
     * @param inArea
     * @throws Exception
     */
    private void checkInWarehouse(String orgId, String inLocation, String inArea) throws Exception {
        if (StringUtils.isBlank(inArea)) {
            return;
        }
        WarehouseDO warehouseDO = warehouseDOMapper.itemByWarehouseCode(orgId, inLocation);
        if (null == warehouseDO) {
            throw new Exception("调入仓库不存在");
        }
        if (null == warehouseAreaDOMapper.itemByCode(orgId,  inArea,warehouseDO.getId())) {
            throw new Exception("调入库区不存在");
        }
    }


    /**
     * 校验调出仓库、库区是否存在
     *
     * @param orgId
     * @param outLocation
     * @param outArea
     * @throws Exception
     */
    private void checkOutWarehouse(String orgId, String outLocation, String outArea) throws Exception {
        if (StringUtils.isBlank(outArea)) {
            return;
        }
        WarehouseDO warehouseDO = warehouseDOMapper.itemByWarehouseCode(orgId, outLocation);
        if (null == warehouseDO) {
            throw new Exception("调出仓库不存在");
        }
        if (null == warehouseAreaDOMapper.itemByCode(orgId, outArea, warehouseDO.getId())) {
            throw new Exception("调出库区不存在");
        }


    }

    /**
     * 校验零件是否重复以及零件是否存在
     *
     * @param materialsNos
     * @param orgId
     * @throws Exception
     */
    private void checkMaterialsNos(List<String> materialsNos, String orgId) throws Exception {
        if (CollectionUtils.isEmpty(materialsNos)) {
            return;
        }
        if (materialsNos.size() != new HashSet<>(materialsNos).size()) {
            throw new Exception("存在重复的零件，请检查");
        }
        for (String materialsNo : materialsNos) {
            if (null == priMaterialsMapper.itemByNo(materialsNo, orgId)) {
                throw new Exception("零件编号" + materialsNo + "不存在");
            }
        }
    }

    /**
     * 校验单据类型
     *
     * @param typeId
     * @throws Exception
     */
    private void checkTypeId(String typeId) throws Exception {
        if (StringUtils.isBlank(typeId)) {
            return;
        }
        if (null == billTypeConfigMapper.selectByPrimaryKey(typeId)) {
            throw new Exception("单据类型不存在");
        }
    }

    /**
     * 校验销售意向单
     *
     * @param saleNo
     * @param orgId
     * @throws Exception
     */
    private void checkSaleNo(String saleNo, String orgId) throws Exception {
        if (StringUtils.isBlank(saleNo)) {
            return;
        }
        if (null == saleIntentionMapper.itemByNo(saleNo, orgId)) {
            throw new Exception("销售意向单号不存在");
        }
    }

    /**
     * 校验非正常退货入库单是否存在
     *
     * @param abnormalInNo
     * @throws Exception
     */
    private void checkAbnormalInNo(String abnormalInNo, String orgId) throws Exception {
        if (StringUtils.isBlank(abnormalInNo)) {
            return;
        }
        if (null == abnormalInMapper.selectByAbnormalNo(abnormalInNo, orgId)) {
            throw new Exception("非正常退货入库单号不存在");
        }
    }

    /**
     * 校验非正常退货出库单是否存在
     *
     * @param abnormalOutNo
     * @throws Exception
     */
    private void checkAbnormalOutNo(String abnormalOutNo, String orgId) throws Exception {
        if (StringUtils.isBlank(abnormalOutNo)) {
            return;
        }
        if (null == abnormalOutMapper.selectByAbnormalNo(abnormalOutNo, orgId)) {
            throw new Exception("非正常退货出库单号不存在");
        }
    }

    /**
     * 校验调入库区和调出库区是否相同
     *
     * @param inLocation
     * @param inArea
     * @param outLocation
     * @param outArea
     * @throws Exception
     */
    private void checkSameWarehouseArea(String inLocation, String inArea, String outLocation, String outArea) throws Exception {
        if (StringUtils.isBlank(inLocation) || StringUtils.isBlank(inArea) || StringUtils.isBlank(outLocation) || StringUtils.isBlank(outArea)) {
            return;
        }
        if (!inLocation.equals(outLocation)) {
            return;
        }
        if (inArea.equals(outArea)) {
            throw new Exception("调入库区与调出库区不能相同");
        }

    }

    /**
     * 校验字典值是否是有效值
     *
     * @param param
     * @throws Exception
     */
    private void checkDictionaryIntegrity(ExternalParamCheckVO param) throws Exception {
//        if (!param.deliveryTypeCorrect()) {
//            throw new Exception("发运方式无效");
//        }
        if (!param.settleTypeCorrect()) {
            throw new Exception("结算方式无效");
        }
        if (!param.purchaseLevelCorrect()) {
            throw new Exception("采购级别无效");
        }
    }
}